package com.wupaas.boot.core.business.oplog;

import cn.afterturn.easypoi.util.PoiReflectorUtil;
import io.swagger.annotations.Api;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 日子拦截器,反射工具类,方便缓存,提高性能
 *
 * @author JueYue
 * @date 2022-05-22-5-22
 * @since 1.0
 */
public class OplogReflect {

    private static final Map<Class<?>, OplogReflect> CACHE_REFLECTOR = new ConcurrentHashMap<>();

    private Map<String, OpLog> opLogMap = new HashMap<>();
    private Map<String, String[]> paramsMap = new HashMap<>();
    private String name;

    public OplogReflect(Class<?> clazz) {
        Method[] method = clazz.getMethods();
        OpLog opLog = null;
        for (Method m : method) {
            if (m.getAnnotation(OpLog.class) != null) {
                opLogMap.put(m.getName() + "_" + m.getParameters().length, m.getAnnotation(OpLog.class));
                String[] params = new String[m.getParameters().length];
                final Parameter[] parameters = m.getParameters();
                for (int i = 0; i < parameters.length; i++) {
                    params[i] = parameters[i].getName();
                }
                paramsMap.put(m.getName() + "_" + m.getParameters().length, params);
            }
        }
        Api api = clazz.getAnnotation(Api.class);
        if (api != null) {
            name = api.value();
        } else {
            OpLogTarget target = clazz.getAnnotation(OpLogTarget.class);
            name = target.name();
        }
    }

    public static OplogReflect fromClass(Class<?> clazz) {
        if (!CACHE_REFLECTOR.containsKey(clazz)) {
            CACHE_REFLECTOR.put(clazz, new OplogReflect(clazz));
        }
        return CACHE_REFLECTOR.get(clazz);
    }

    public OpLog getOplog(String key) {
        return opLogMap.get(key);
    }

    public String[] getParam(String key) {
        return paramsMap.get(key);
    }

    public String getName() {
        return name;
    }
}
